package com.base_data_handler.surfer;

import java.io.File;
import java.util.Date;

import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.ComThread;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
/**
 * ClassName:Surfer
 * Description:surfer等值面绘图工具类
 * Writer: CCT
 * Create Date:2015年09月17日 上午10:26:23 
 * Rewriter: XY
 * Rewrite Date:2017年05月13日 上午11:26:23 
 * Rewrite remark:调整格点数据创建方法，增加绘图功能及美化
 * Version:
 */
public class Surfer {

	private ActiveXComponent surferComponent;
	private Dispatch surferObject;// surfer对象
	private Dispatch surferDocument; // sufer文档
	private String fileLeftName;
	private String outGrid;// Grid文件
	private String pngFileName ;//产生的图片名
	/**
	 * 打开数据产生Grid网格数据
	 * @param path源数据文件 路径名称
	 * @param xmin，xmax，ymin，ymax  经纬度范围
	 * @param Algo 插值方法
	 */
	String filepath = "F:\\surfer绘图\\绘图调用文件\\"; //绘图文件调用文件路径（包括白化、边界、grd、配色、图例、站点、数据文件等）
	public void openDataFile(String path, double xmin, double xmax, double ymin, double ymax,int Algo) {
		try{
			surferComponent = new ActiveXComponent("Surfer.Application");
			surferObject = surferComponent.getObject();
			Dispatch.put(surferObject, "Visible", new Variant(false));
			java.text.DateFormat format2 = new java.text.SimpleDateFormat("yyyyMMddhhmmssSSS");
			fileLeftName = format2.format(new Date());
			outGrid = filepath + "grid" + fileLeftName + ".grd";
			// 网格化数据
			Variant[] args = new Variant[] { 
				new Variant(path), // string
				new Variant(1), // x经度为第一列数据 [int xCol = 0],
				new Variant(2), // y纬度为第二列数据 [int yCol = 0],
				new Variant(3), // z为第三列数据 [int zCol = 0],
				Variant.DEFAULT, // [object ExclusionFilter = System.Type.Missing],
				Variant.DEFAULT,//new Variant(SrfDupMethod.srfDupNone), // [object DupMethod = System.Type.Missing],
				Variant.DEFAULT,// [object xDupTol = System.Type.Missing],
				Variant.DEFAULT,// [object yDupTol = System.Type.Missing],
			    new Variant(600),// new Variant("NumCols "), numCols, //x方向插值数据量
								// [object NumCols = System.Type.Missing],
			    new Variant(600),// new Variant("NumRows"), numRows, //y方向插值数据量
								// [object NumRows = System.Type.Missing],
			    new Variant(xmin),// new Variant("xMin"), xmin, //x最小值 [object
								// xMin = System.Type.Missing],
			    new Variant(xmax),// new Variant("xMax"), xmax, //x最大者 [object
			    				// xMax = System.Type.Missing],
			    new Variant(ymin),// new Variant("yMin"), ymin, //y最小值 [object
								// yMin = System.Type.Missing],
			    new Variant(ymax),// new Variant("yMax"), ymax, //y最大值 [object
								// yMax = System.Type.Missing],
			    new Variant(Algo),// [object Algorithm = System.Type.Missing],
				new Variant(false),// [object ShowReport = System.Type.Missing],
				Variant.DEFAULT,// [object SearchEnable = System.Type.Missing],
				Variant.DEFAULT,// [object SearchNumSectors = System.Type.Missing],
				Variant.DEFAULT,// [object SearchRad1 = System.Type.Missing],
				Variant.DEFAULT,// [object SearchRad2 = System.Type.Missing],
				Variant.DEFAULT,// [object SearchAngle = System.Type.Missing],
				Variant.DEFAULT,// [object SearchMinData = System.Type.Missing],
				Variant.DEFAULT,// [object SearchDataPerSect =
								// System.Type.Missing],
				Variant.DEFAULT,// [object SearchMaxEmpty =
								// System.Type.Missing],
				Variant.DEFAULT,// [object FaultFileName = System.Type.Missing],
				Variant.DEFAULT,// [object BreakFileName = System.Type.Missing],
 				Variant.DEFAULT,// [object AnisotropyRatio =
								// System.Type.Missing],
				Variant.DEFAULT,// [object AnisotropyAngle =
								// System.Type.Missing],
				Variant.DEFAULT,// [object IDPower = System.Type.Missing],
				Variant.DEFAULT,// [object IDSmoothing = System.Type.Missing],
				Variant.DEFAULT,//new Variant(SrfGridAlgorithm.srfKriging), // 插值算法Kriging [object
								// KrigType =System.Type.Missing],
				Variant.DEFAULT,// [object KrigDriftType = System.Type.Missing],
				Variant.DEFAULT,// [object KrigStdDevGrid =System.Type.Missing],
				Variant.DEFAULT,// [object KrigVariogram = System.Type.Missing],
				Variant.DEFAULT,// [object MCMaxResidual = System.Type.Missing],
				Variant.DEFAULT,// [object MCMaxIterations =
								// System.Type.Missing],
				Variant.DEFAULT,// [object MCInternalTension =
								// System.Type.Missing],
				Variant.DEFAULT,// [object MCBoundaryTension =
								// System.Type.Missing],
				Variant.DEFAULT,// [object MCRelaxationFactor =
								// System.Type.Missing],
				Variant.DEFAULT,// [object ShepSmoothFactor =
								// System.Type.Missing],
				Variant.DEFAULT,// [object ShepQuadraticNeighbors =
								// System.Type.Missing],
				Variant.DEFAULT,// [object ShepWeightingNeighbors =
								// System.Type.Missing],
				Variant.DEFAULT,// [object ShepRange1 = System.Type.Missing],
				Variant.DEFAULT,// [object ShepRange2 = System.Type.Missing],
				Variant.DEFAULT,// [object RegrMaxXOrder = System.Type.Missing],
				Variant.DEFAULT,// [object RegrMaxYOrder = System.Type.Missing],
				Variant.DEFAULT,// [object RegrMaxTotalOrder =
								// System.Type.Missing],
				Variant.DEFAULT,// [object RBBasisType = System.Type.Missing],
				Variant.DEFAULT,// [object RBRSquared = System.Type.Missing],
				new Variant(outGrid), // 返回文件为gridfile [string OutGrid = ""],
				new Variant(SrfGridFormat.srfGridFmtAscii), // 返回文件编码为Ascii
															// [Surfer.SrfGridFormat
															// OutFmt =
															// Surfer.SrfGridFormat.srfGridFmtS7],
				Variant.DEFAULT,// [object SearchMaxData = System.Type.Missing],
				Variant.DEFAULT,// [object KrigStdDevFormat =
								// System.Type.Missing],
				Variant.DEFAULT,// [object DataMetric = System.Type.Missing],
				Variant.DEFAULT,// [object LocalPolyOrder =
								// System.Type.Missing],
				Variant.DEFAULT,// [object LocalPolyPower =
								// System.Type.Missing],
				Variant.DEFAULT // [object TriangleFileName =
								// System.Type.Missing])
			};	

		    Dispatch.call(surferObject, "GridData", args); // 调用 GridData方法
		}catch(Exception e){
			e.printStackTrace();
			System.out.println(e.getMessage());
		}
	}

	/**
	 * 获取等值面图片名
	 * 
	 * @param fileSavePath 生成图片保存路径
	 * @param datName 站点标注文件
	 * @param lvlName 配色文件
	 * @param blankName 白化文件
	 * @param blnName 边界文件
	 * @param MapName 图例文件
	 * @param IsShowColorScale 是否显示色柱
	 * @param Title 标题
	 * @param picWidth 生成图片宽度
	 * @param PicHeight 生成图片高度
	 * @return
	 */
	public String getSurfacePic(String fileSavePath,String datName, String lvlName, String blankName, String blnName, String MapName, Boolean IsShowColorScale, String Title, int picWidth, int PicHeight,Boolean IsFillContour) {
      try{
			if (null == surferObject)
				return "";
			Dispatch surferDocuments = surferComponent.getProperty("Documents").toDispatch(); // sufer文档集合
			surferDocument = Dispatch.call(surferDocuments, "Add",SrfDocTypes.srfDocPlot).toDispatch(); // 新建一个srfDocPlot 文档	 
			Boolean gridSucss=Dispatch.call(surferObject, "GridBlank",outGrid,  filepath +"\\"+ blankName, outGrid, SrfGridFormat.srfGridFmtBinary).toBoolean();
			Dispatch shapes = Dispatch.get(surferDocument, "Shapes").toDispatch();
			Dispatch contourMapFrame = Dispatch.call(shapes, "AddContourMap",	outGrid).toDispatch(); // 加载网格数据.
			double Left= Dispatch.get(contourMapFrame, "Left").getDouble();
	    	double Top= Dispatch.get(contourMapFrame, "Top").getDouble();
	    	double Height= Dispatch.get(contourMapFrame, "Height").getDouble();
	    	double Width=Dispatch.get(contourMapFrame, "Width").getDouble();
			//坐标轴设置
			Dispatch Axes = Dispatch.get(contourMapFrame, "Axes").toDispatch();
			int countryaxesCnt = Axes.get(Axes, "Count").getInt();
			for (int i = 1; i <=  countryaxesCnt; i++) 
			{ 
				Dispatch item= Dispatch.call(Axes, "Item",i).toDispatch();
				Dispatch LabelFormat = Dispatch.get(item, "LabelFormat").toDispatch();
				Dispatch.put(item, "Visible", true); //隐藏轴线 
				if(i==1){
					Dispatch.put(item, "ShowLabels", true);  //显示X轴线上的坐标 
					Dispatch.put(LabelFormat, "Postfix", "°E");//坐标添加后缀°E
					Dispatch.put(item, "MajorTickType", new Variant(SrfTickType.srfTickOut)); //隐藏边线 
				}
				else if(i==3){
					Dispatch.put(item, "ShowLabels", true);  //显示Y轴线上的坐标 
					Dispatch.put(LabelFormat, "Postfix", "°N");//坐标添加后缀°N
					Dispatch.put(item, "MajorTickType", new Variant(SrfTickType.srfTickOut)); //隐藏边线 
				}
				else if(i==2 || i==4){
					Dispatch.put(item, "MajorTickType", new Variant(SrfTickType.srfTickNone)); //坐标在轴线上显示方式
				}
			} 
			//添加边界文件
			Dispatch countryframe0=Dispatch.call(shapes, "AddBaseMap",filepath + "\\" + blnName, "Defaults=1").toDispatch() ;
			Dispatch counterMap0=Dispatch.call(Dispatch.get(countryframe0, "Overlays").toDispatch() , "Item",1).toDispatch() ;
			/*Dispatch line1 = Dispatch.get(counterMap0, "Line").toDispatch();
			Dispatch.put(line1, "Width",new Variant(0.01));*/
			//添加站点信息标注
			if(!datName.equals(""))
			{
				Dispatch Post=Dispatch.call(shapes,"AddPostMap",filepath + "\\" + datName,1,2,3,0,0).toDispatch() ;
				Dispatch PostMap=Dispatch.call(Dispatch.get(Post, "Overlays").toDispatch() , "Item",1).toDispatch() ;
				Dispatch.put(PostMap, "LabelPos", SrfPostPosType.srfPostPosBelow); //设置站点名显示在点下方
				Dispatch LabelFont = Dispatch.get(PostMap, "LabelFont").toDispatch();//设置站点名字体大小
				Dispatch.put(LabelFont, "Face", "宋体");
				Dispatch.put(LabelFont, "Size", 9);
				Dispatch Symbol = Dispatch.get(PostMap, "Symbol").toDispatch(); //设置标注点形状、颜色、大小
				Dispatch.put(Symbol, "Index", 12);
				Dispatch.put(Symbol, "Color", SrfColor.srfColorOrange);
				Dispatch.put(Symbol, "Size", 0.04);
			}
			if(!datName.equals(""))
			{
				Dispatch Post=Dispatch.call(shapes,"AddPostMap",filepath + "\\zuoye.dat",1,2,3,0,0).toDispatch() ;
				Dispatch PostMap=Dispatch.call(Dispatch.get(Post, "Overlays").toDispatch() , "Item",1).toDispatch() ;
				Dispatch.put(PostMap, "LabelPos", SrfPostPosType.srfPostPosBelow); //设置站点名显示在点下方
				Dispatch LabelFont = Dispatch.get(PostMap, "LabelFont").toDispatch();//设置站点名字体大小
				Dispatch.put(LabelFont, "Face", "宋体");
				Dispatch.put(LabelFont, "Size", 9);
				Dispatch Symbol = Dispatch.get(PostMap, "Symbol").toDispatch(); //设置标注点形状、颜色、大小
				Dispatch.put(Symbol, "Index", 15);
				Dispatch.put(Symbol, "Color", SrfColor.srfColorBlack);
				Dispatch.put(Symbol, "Size", 0.46);
				Dispatch.put(PostMap, "Opacity", 30);
			}
			//配色文件lvl或clr等值线填充,lvl层级文件（颜色可自己设置，无渐变）,clr色谱文件（可设置一个颜色分布，渐变）
			Dispatch counterMap=Dispatch.call(Dispatch.get(contourMapFrame, "Overlays").toDispatch() , "Item",1).toDispatch() ;
			if(!lvlName.equals(""))
			{
				if(lvlName.contains(".lvl") ){
				    Dispatch.call(  Dispatch.get(counterMap,"Levels"  ).toDispatch() , "LoadFile" ,  filepath +"\\" + lvlName );
				}else{
					Dispatch.call( Dispatch.get(counterMap, "FillForegroundColorMap") .toDispatch()    , "LoadFile",   filepath + "\\"	+ lvlName); //加载色标
					Dispatch.call(counterMap, "ApplyFillToLevels",1,1,0);
				}
			}
			Dispatch levels = Dispatch.get(counterMap, "Levels").toDispatch();	//// 色标区块		
			int cnt = levels.get(levels, "Count").getInt();
			for (int i = 1; i <= cnt; i++)// 设置等值线的样式
			{
				Dispatch item= levels.call(levels, "Item",i).toDispatch();
				item.put(item, "ShowLabel", false); //显示等值线上的数值 
				item.put(item, "ShowHach", false); //
				//item.put( Dispatch.get(item, "Line").toDispatch() , "Style", new Variant("Solid")); //线样式
				item.put( Dispatch.get(item, "Line").toDispatch() , "Style", new Variant("Invisible"));
				//item.put( Dispatch.get(item, "Line").toDispatch() , "Color", new Variant("Blue")); //线颜色
			}
			Dispatch.put(counterMap, "SmoothContours", SrfConSmoothType.srfConSmoothHigh);//设置平滑度
			Dispatch.put(counterMap, "FillContours", IsFillContour);//是否填充
			Dispatch.put(counterMap, "ShowColorScale", IsShowColorScale);//显示色标
			
			
			//合并图层
			Dispatch win= Dispatch.call(surferObject, "Windows",1).toDispatch();
		    Dispatch.call(win,"Redraw");	//刷新屏幕
			Dispatch.call(shapes,"SelectAll");	
			Dispatch selected=  Dispatch.get(surferDocument, "Selection").toDispatch();// 返回所有选中对象
		    Dispatch.call(selected, "OverlayMaps");//将图层合并
            //添加图例
		    if (!MapName.equals(""))
            {
		    	Dispatch MapL=Dispatch.call(shapes, "AddBaseMap",filepath + "\\" + MapName, "Defaults=1").toDispatch() ;
		    	Dispatch.put(MapL, "Selected", true);
		    	Dispatch.put(MapL, "Width", 1.6);
		    	Dispatch.put(MapL, "Height", 1.4);
		    	Dispatch.put(MapL, "Left", Left + 0.28);
		    	Dispatch.put(MapL, "Top", Top-Height+1.6);
		    	Dispatch AxesMapL = Dispatch.get(MapL, "Axes").toDispatch();
		    	Dispatch item1= Dispatch.call(AxesMapL, "Item",1).toDispatch();
		    	Dispatch item2= Dispatch.call(AxesMapL, "Item",2).toDispatch();
		    	Dispatch item3= Dispatch.call(AxesMapL, "Item",3).toDispatch();
		    	Dispatch item4= Dispatch.call(AxesMapL, "Item",4).toDispatch();
		    	Dispatch.put(item1, "MajorTickType", new Variant(SrfTickType.srfTickNone)); //坐标在轴线上显示方式
		    	Dispatch.put(item2, "MajorTickType", new Variant(SrfTickType.srfTickNone));
		    	Dispatch.put(item3, "MajorTickType", new Variant(SrfTickType.srfTickNone));
		    	Dispatch.put(item4, "MajorTickType", new Variant(SrfTickType.srfTickNone));
            }
		    //添加标题
		    if (!Title.equals(""))
		    {
		    	double xPos = (Width + Left * 2) / 2;
                double yPos = Top + 0.2;
                Dispatch Text1=Dispatch.call(shapes, "AddText",xPos, yPos, Title).toDispatch() ;
                Dispatch Font = Dispatch.get(Text1, "Font").toDispatch();
                Dispatch.put(Font, "Face", "宋体");
                Dispatch.put(Font, "Size", 12);
                Dispatch.put(Font, "HAlign", SrfHTextAlign.srfTACenter);
		    }
		    //添加色柱到图片左下角
		    if (IsShowColorScale == true)
            {
		    	Dispatch ColorScale = Dispatch.get(counterMap, "ColorScale").toDispatch();//色标属性
		    	double ColWidth = Dispatch.get(ColorScale, "Width").getDouble();
		    	/*Dispatch.put(ColorScale, "Top", Top/2+0.5);
		    	Dispatch.put(ColorScale, "Left", Left+ColWidth+0.2);
		    	Dispatch.put(ColorScale, "Height", Height/3);*/
            }
			String strWH = "Width = " + picWidth + ", Height = " + PicHeight + " ,ColorDepth = 32";// 设置输出图片的高度和宽度
		    pngFileName = fileLeftName + ".png";
			Dispatch.call(surferDocument, "Export", fileSavePath + pngFileName,new Variant(false), strWH);////导出为固定格式png文件
			Dispatch.call(surferDocument, "Close", SrfSaveTypes.srfSaveChangesNo); //不生成srf文件
			quit();
			clearData(fileSavePath);
			//return fileSavePath+pngFileName;
			return pngFileName;
		}catch(Exception e){
			e.printStackTrace();
			ComThread.Release();
			return "该要素的数据无法完成绘图";
		}
	}

	/**
	 * 清除数据
	 */
	private void clearData(String fileSavePath) {
		File file = new File(outGrid);
		if (file.exists()) {
			file.delete();
		}
		file = new File(fileSavePath+pngFileName+".gsr2");
		if (file.exists()) {
			file.delete();
		}
		file = new File(filepath+"surfer.txt");
		if (file.exists()) {
			file.delete();
		}
	}

	/**
	 * 退出程序
	 */
	public void quit() {

		if (null == surferObject)
			return;
		if (null != surferDocument){
		   // Dispatch.call(surferDocument, "Close", new Variant(1), new Variant("d:\\srfFile\\"+srfFileName+".srf"));// 生成srf文件
			Dispatch.call(surferObject, "Quit");
			ComThread.Release();
		}
	}
 
	public static void main(String[] args) {
//		new Surfer().getSurfacePic(fileSavePath, datName, lvlName, blankName, blnName, MapName, IsShowColorScale, Title, picWidth, PicHeight, IsFillContour)
	}
}
